package com.ideazd.api.controller;

import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.ideazd.api.model.AccountedIn;
import com.ideazd.api.model.OrderDetails;
import com.ideazd.api.model.OrderSummary;
import com.ideazd.api.pay.Pay;
import com.ideazd.api.tools.DateUtil;
import com.ideazd.api.tools.SysUtil;
import com.ideazd.common.utils.StringUtil;
import com.jfinal.aop.Before;
import com.jfinal.core.Controller;
import com.jfinal.ext.route.ControllerBind;
import com.jfinal.kit.HttpKit;
import com.jfinal.log.Logger;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.DbKit;
import com.jfinal.plugin.activerecord.tx.Tx;

@ControllerBind(controllerKey = "/pay")
public class PayController extends Controller {
	private static final Logger log = Logger.getLogger(PayController.class);
	
	// 支付宝回调
	@Before(Tx.class)
	public void callbackZFB() {
		String out_trade_no = getPara("out_trade_no");
		String trade_no = getPara("trade_no"); // 支付宝订单号
		String pay_money = getPara("price");
		String trade_status = getPara("trade_status"); // 支付状态
		Map<String, String> returnMap = new HashMap<String, String>();

		try {
			

			if (StringUtil.isEqual(trade_status, "TRADE_SUCCESS")) {
				returnMap.put("code", "0");
				returnMap.put("msg", "支付成功");
				String orderSummarySlq = "update sta_order_summary set payordernumber = '"+trade_no+"',mortgageamount=0,paytype='02',paystatus='02',paytime=now(),payuseid=useid,payamount='"+pay_money+"',updatedate=now(),remarks='支付宝支付订单'";
				if(Db.update(orderSummarySlq) > 0){
					
					OrderSummary orderSummary = OrderSummary.dao.findFirst("select * from sta_order_summary where ordernumber='"+out_trade_no+"'");
					
					List<OrderDetails> orderDetails = OrderDetails.dao.find("select * from sta_order_details where ordid='"+orderSummary.get("ordid")+"'");
					
					for(OrderDetails o:orderDetails){
						Db.update("update sta_commodity_version set version_stock = version_stock-"+o.get("buynumber")+" where id='"+o.get("modid")+"'");
					}
					
					AccountedIn accountedIn = new AccountedIn();
					accountedIn.set("accinid", SysUtil.getUUID());
					accountedIn.set("ordid", orderSummary.get("ordid"));
					accountedIn.set("ordnumber", orderSummary.get("ordernumber"));
					accountedIn.set("useid",orderSummary.get("useid"));
					accountedIn.set("payorderid", trade_no);
					accountedIn.set("intime", new Date());
					accountedIn.set("inamount", pay_money);
					accountedIn.set("intype", "02");
					accountedIn.set("createid", orderSummary.get("useid"));
					accountedIn.set("createname", "支付宝回调创建");
					accountedIn.set("createdate", new Date());
					accountedIn.set("updateid", orderSummary.get("useid"));
					accountedIn.set("updatename", "支付宝回调创建");
					accountedIn.set("updatedate", new Date());
					accountedIn.set("remarks", "支付宝回调创建");
					accountedIn.save();
				}
							
				
			} else {
				returnMap.put("cod","1");
				returnMap.put("msg", "支付失败");
				renderJson("");
				return;
			}
		} catch (Exception e) {
			returnMap.put("code", "-1");
			returnMap.put("msg", "服务器错误");
			try {
				DbKit.getConfig().getConnection().rollback();
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				System.out.println(e1.getErrorCode());
			}
		}
		renderJson("SUCCESS");
		return;
	}
	
	
	// 生成微信订单
	public void createWXPayOrder()throws Exception {
			String ip = getPara("ip");
			String payMoney = getPara("totalPrice");
			String appId = getPara("appId");
			String partnerId = getPara("partnerId");
			String paySignKey = getPara("paySignKey");
			String order_no = getPara("orderNo");
			BigDecimal allprice = new BigDecimal(payMoney);
			double fprice = allprice.doubleValue();
			int total_fee = (int) (fprice * 100);
			
			String result = submitWx(ip,appId,partnerId,paySignKey,order_no,total_fee);
			//重复订单
			if(result.indexOf("商户订单号重复")>-1){
				String new_order_no = order_no.substring(0, 2) + DateUtil.formatDate(new Date(),"yyyyMMddHHmmssSSS");
				if(order_no.substring(0, 2).equals("op")){
					Db.update("update fsj_purchase_onepurchase_buy_total set order_no = '"+new_order_no+"' where order_no='"+order_no+"'");
				}else{
					Db.update("update fsj_purchase_commodity_buy_total set order_no = '"+new_order_no+"' where order_no='"+order_no+"'");
				}
				
				result = submitWx(ip,appId,partnerId,paySignKey,new_order_no,total_fee);
				
				
			}
			
			System.out.println(result);
			renderJson(payJson(result, fprice + "", appId, paySignKey, partnerId));
			return;
	}
	
	private String submitWx(String ip,String appId,String partnerId,String paySignKey,String order_no,int total_fee){
		String orderUrl = "";
		
		try {
			System.out.println("total_fee---->" + total_fee);
			// 参数
			Map<String, String> params = new HashMap<String, String>();
			System.out.println("orderid------>" + "wx734304a88551aca1");
			String nonceStr = StringUtil.getRoundNum(8); // 8位随机数
			params.put("appid", appId); // 公众号id
			params.put("mch_id", partnerId); // 商户id
			params.put("nonce_str", nonceStr); // 随机数 少于32位即可
			params.put("body", "商品订单支付"); // 商品描述。
			params.put("out_trade_no", order_no); // 商户系统内部的订单号
			params.put("total_fee", total_fee + ""); // 订单总金额 为整形 单位（分）
			params.put("spbill_create_ip", ip); // ip
			params.put("trade_type", "APP"); // 支付方式 JSAPI
			params.put("notify_url", "http://api.fansiji.com/fsj_api/api/pay/callbackWX"); // 统一下单成功后回调url
			String packagestring;
		
			packagestring = Pay.setSign(params, paySignKey);
			System.out.println("sign-------->" + packagestring);
			//String timeStamp = System.currentTimeMillis() + ""; // 时间戳i
			orderUrl = "appid=" + appId + "&mch_id=" + partnerId;
			orderUrl += "&nonce_str=" + nonceStr + "&sign=" + packagestring
					+ "&body=" + "商品订单支付" + "&out_trade_no=" + order_no;
			orderUrl += "&total_fee=" + total_fee + "&spbill_create_ip=" + ip
					+ "&trade_type=APP&notify_url=http://api.fansiji.com/fsj_api/api/pay/callbackWX";
			System.out.println(orderUrl);
			// 将键值对转换成xml字符串
			orderUrl = Pay.keyvalue2XML(orderUrl);
			System.out.println(orderUrl);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} // 构造签名
		
		// 统一下单 注：一定要用post请求
		return HttpKit.post(
				"https://api.mch.weixin.qq.com/pay/unifiedorder", orderUrl);
	}

	public static Map<Object,Object> payJson(String result, String pay_money, String appId,
			String paySignKey, String partnerId) throws Exception {
		Map<Object,Object> res = new HashMap<Object,Object>();
		String prepay_id = "";
		if (StringUtil.isEmpty(result)) {
			res.put("code", "-1");
			res.put("msg", "无效的参数！");
		} else {
			result = URLDecoder.decode(result, "utf-8");
			Map<String, String> map = Pay.xml2Map(result);
			String return_code = map.get("return_code");
			if ("FAIL".equals(return_code)) {
				res.put("code", -1);
				res.put("msg", "支付认证失败！");
			} else {
				prepay_id = map.get("prepay_id");
				System.out.println("prepay_id---------------" + prepay_id);
				// package 参数------------------------------ //
				Map<String, String> params = new HashMap<String, String>();
				// 参数
				String timeStamp = System.currentTimeMillis() + ""; // 时间戳
				System.out.println("timeStamp---------------" + timeStamp);
				String nonceStr = StringUtil.getRoundNum(8); // 8位随机数
				params.put("appid", appId); // appId
				params.put("partnerid", partnerId); // appId
				params.put("timestamp", timeStamp.substring(0, 10));
				params.put("noncestr", nonceStr); // 随机数 小于32位即可
				params.put("prepayid", prepay_id); // 重要参数
				params.put("package", "Sign=WXPay"); // 重要参数
				String paySign = Pay.setSign(params, paySignKey); // 构造签名
				System.out.println(paySign);
				params.put("paySign", paySign); // 加密方式
				params.put("packageStr", "prepay_id=" + prepay_id); // 加密方式
				res.put("code", "0");
				res.put("msg", "");
				res.put("data", params);
				res.put("pay_money", pay_money);
				
				/*Map<Object,Object> re = new HashMap<Object,Object>();
				re.put("prepayId", prepay_id);
				re.put("sign", paySign);
				res.put("data", re);*/
			}
		}
		return res;
	}
	
	/**
	 * 微信回调函数
	 */
	@Before(Tx.class)
	public void callbackWX() {
		HttpServletRequest request = getRequest();
		Map<String, String> map = new HashMap<String, String>();
		InputStream inputStream;
		
		try {
			inputStream = request.getInputStream();
			// 读取输入流
			SAXReader reader = new SAXReader();
			Document document = reader.read(inputStream);
			// 得到xml根元素
			Element root = document.getRootElement();
			// 得到根元素的所有子节点
			List<Element> elementList = root.elements();
			// 遍历所有子节点
			for (Element e : elementList)
				map.put(e.getName(), e.getText());
			// 释放资源
			inputStream.close();
			inputStream = null;
			//String from_user = map.get("openid");
			String out_trade_no = map.get("out_trade_no");
			String pay_order_no = map.get("transaction_id");
			String result_code = map.get("result_code");
			String return_code = map.get("return_code");
			BigDecimal pay_money = new BigDecimal(map.get("cash_fee").toString())
			.divide(new BigDecimal("100"));

			System.out.println("map:" + map);
			System.out.println("out_trade_no:" + map.get("out_trade_no"));
			System.out.println("transaction_id:" + map.get("transaction_id"));
			System.out.println("result_code:" + map.get("result_code"));
			System.out.println("return_code:" + map.get("return_code"));
			System.out.println("openid:" + map.get("openid"));
			System.out.println(map.get("cash_fee"));
			
			String str = "";
			if (StringUtil.isEqual(result_code, "SUCCESS") && StringUtil.isEqual(return_code, "SUCCESS")) {
				String orderSummarySlq = "update sta_order_summary set payordernumber = '"+out_trade_no+"',mortgageamount=0,paytype='01',paystatus='02',paytime=now(),payuseid=useid,payamount='"+pay_money+"',updatedate=now(),remarks='微信支付订单'";
				if(Db.update(orderSummarySlq) > 0){
					
					OrderSummary orderSummary = OrderSummary.dao.findFirst("select * from sta_order_summary where ordernumber='"+out_trade_no+"'");
					
					List<OrderDetails> orderDetails = OrderDetails.dao.find("select * from sta_order_details where ordid='"+orderSummary.get("ordid")+"'");
					
					for(OrderDetails o:orderDetails){
						Db.update("update sta_commodity_version set version_stock = version_stock-"+o.get("buynumber")+" where id='"+o.get("modid")+"'");
					}
					
					
					
					AccountedIn accountedIn = new AccountedIn();
					accountedIn.set("accinid", SysUtil.getUUID());
					accountedIn.set("ordid", orderSummary.get("ordid"));
					accountedIn.set("ordnumber", orderSummary.get("ordernumber"));
					accountedIn.set("useid",orderSummary.get("useid"));
					accountedIn.set("payorderid", pay_order_no);
					accountedIn.set("intime", new Date());
					accountedIn.set("inamount", pay_money);
					accountedIn.set("intype", "01");
					accountedIn.set("createid", orderSummary.get("useid"));
					accountedIn.set("createname", "微信回调创建");
					accountedIn.set("createdate", new Date());
					accountedIn.set("updateid", orderSummary.get("useid"));
					accountedIn.set("updatename", "微信回调创建");
					accountedIn.set("updatedate", new Date());
					accountedIn.set("remarks", "微信回调创建");
					accountedIn.save();
				}
			} // Pay.keyvalue2XML
			str = "return_code=<![CDATA[SUCCESS]]>&return_msg=<![CDATA[OK]]>";
			str = Pay.keyvalue2XML(str);
			System.out.println(str);
			renderJson("SUCCESS");
			//renderNull();
			
		}catch (Exception e) {
			try {
				DbKit.getConfig().getConnection().rollback();
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				System.out.println(e1.getErrorCode());
			}
			System.out.println(e);
			renderNull();
		}
	}
	
}
